/**
 * Definition for singly-linked list.
 * function ListNode(val) {
 *     this.val = val;
 *     this.next = null;
 * }
 */
/**
 * @param {ListNode} head
 * @param {number} k
 * @return {ListNode}
 */
var reverseKGroup = function(head, k) {
  let c = head;
  let reversedSize = reverseFirstK(c, k);
  while (reversedSize >= k) {
    c = kthNode(c, k);
    reversedSize = reverseFirstK(c, k);
  }
  return head;
};

function reverseFirstK(head, k) {
  const li = [];
  for (let i = 0, c = head; i < k; i++, c = c.next) {
    if (c != null) li.push(c.val);
    else return i; // 长度不够，提前结束
  }
  const lilen = li.length;
  for (let i = 0, c = head; i < k; i++, c = c.next) {
    if (c != null) {
      c.val = li.pop();
    } else break;
  }
  return lilen;
}

function kthNode(node, k) {
  let c = node;

  for (let i = 0; i < k; i++, c = c.next) {
    if (c == null) return null;
  }
  return c;
}

// ------------------------------------------------------------------------------------------
// ------------------------------------------------------------------------------------------
// ------------------------------------------------------------------------------------------
// ------------------------------------------------------------------------------------------
// ------------------------------------------------------------------------------------------

function ListNode(val, next = null) {
  this.val = val;
  this.next = next;
  this.toString = () => {
    const current = '' + this.val + ', ';
    const nextStr = this.next === null ? '' : this.next.toString();
    return current + nextStr;
  };
}

const li = new ListNode(1, new ListNode(2, new ListNode(3, new ListNode(4, new ListNode(5)))));
console.log(reverseKGroup(li, 2).toString());

const li2 = new ListNode(1, new ListNode(2, new ListNode(3, new ListNode(4, new ListNode(5)))));
console.log(reverseKGroup(li2, 3).toString());
